import { ElMessage } from 'element-plus';
import { generateUUID, getRandomInteger } from '@/utils/common';
import { scheduleJob, cancelJob } from 'node-schedule'
import { sendTextMsg, sendImageMsg, sendFileMsg } from "@/api/wxauto";

class NowTask {
  //  构造函数
  constructor(opt, callback, output, config) {
    this.id = generateUUID()
    this.createTime = new Date().toLocaleString()
    this.contrast = opt.contrast
    this.content = opt.content
    this.type = opt.type // 0-即时 1-定时
    this.state = 0 //  0-等待 1-执行中 2-暂停 3-取消 4-完成
    this.intervalId = undefined
    this.personIndex = 0
    this.msgIndex = 0
    this.callback = callback
    this.output = output
    this.config = config
  }
  execute() {
    if (this.state == 0 || this.state == 2) {
      this.state = 1
      this.doSend()
    }
  }

  stop() {
    this.state = 2
    this.clearIntervalId()
  }

  cancel() {
    this.state = 3
    this.clearIntervalId()
  }

  finish() {
    this.state = 4
    this.clearIntervalId()
    this.callback(this)
  }

  async doSend() {
    if (this.personIndex < this.contrast.length) {
      const person = this.contrast[this.personIndex];
      const msg = this.content[this.msgIndex];
      await this.realSend(person, msg)

      this.msgIndex++;
      if (this.msgIndex < this.content.length) {
        this.intervalId = setTimeout(() => {
          this.doSend()
        }, getRandomInteger(this.config.msgMinInterval, this.config.msgMaxInterval) * 1000);
      } else {
        this.personIndex++;
        if (this.personIndex == this.contrast.length) {
          this.finish()
          return
        }
        this.msgIndex = 0
        this.intervalId = setTimeout(() => {
          this.doSend()
        }, getRandomInteger(this.config.personMinInterval, this.config.personMaxInterval) * 1000);
      }
    }
  }

  async realSend(person, msg) {
    if (msg.type === 'text') {
      await sendTextMsg(person.wxid, msg.content)
    } else if (msg.type === 'image') {
      await sendImageMsg(person.wxid, msg.content)
    } else if (msg.type === 'file') {
      await sendFileMsg(person.wxid, msg.content)
    }
    this.output(`${new Date().toLocaleString()} 向 ${person.nickname} 发送: ${msg.content}`)
  }

  clearIntervalId() {
    if (this.intervalId) {
      clearInterval(this.intervalId)
      this.intervalId = undefined
    }
  }
}

class TimedTask {
  constructor(opt) {
    this.id = generateUUID()
    this.createTime = new Date().toLocaleString()
    this.contrast = opt.contrast
    this.content = opt.content
    this.time = opt.time
    this.timeTag = opt.timeTag
    this.state = 0 //  0-等待 1-执行中 2-暂停 3-取消 4-完成
    this.type = 1 // 0-即时 1-定时
  }
}

export default {
  state: {
    nowTaskList: [],
    timedTaskList: [],
    intervalId: undefined,
    logList: []
  },
  getters: {
    getNowTask(state) {
      return state.nowTaskList[0]
    }
  },
  mutations: {
    removeNowTask(state, task) {
      state.nowTaskList = state.nowTaskList.filter(item => item.id !== task.id)
    },
    removeTimedTask(state, task) {
      state.timedTaskList = state.timedTaskList.filter(item => item.id !== task.id)
    },
    clearIntervalId(state) {
      if (state.intervalId) {
        clearInterval(state.intervalId)
        state.intervalId = undefined
      }
    },
    addLog(state, log) {
      state.logList.push(log)
    },
    clearLog(state) {
      state.logList = []
    },
  },
  actions: {
    addNowTask({ state, rootState, commit, dispatch, getters }, opt) {
      const task = new NowTask(opt,
        (item) => {   //callback
          commit('removeNowTask', item)
          const nextTask = getters.getNowTask
          if (nextTask) {
            state.intervalId = setTimeout(() => { nextTask.execute() }, 1000)
          } else {
            ElMessage.success('任务执行完成')
          }
        }, (log) => { // output
          commit('addLog', log)
        }, {
        //config
        personMinInterval: rootState.config.personMinInterval,
        personMaxInterval: rootState.config.personMaxInterval,
        msgMinInterval: rootState.config.msgMinInterval,
        msgMaxInterval: rootState.config.msgMaxInterval,
      })
      state.nowTaskList.push(task)
    },
    startNowTask({ state, commit, getters }) {
      const task = getters.getNowTask
      if (task) {
        task.execute()
      }
    },
    stopNowTask({ state, commit, getters }) {
      commit('clearIntervalId')
      const task = getters.getNowTask
      if (task) {
        task.stop()
      }
    },
    cancelNowTask({ state, commit }, action) {
      commit('clearIntervalId')
      const { task } = action
      task.cancel()
      commit('removeNowTask', task)
    },
    addTimedTask({ state, rootState, commit, dispatch, getters }, opt) {
      const task = new TimedTask(opt)
      scheduleJob(task.id, task.time, () => {
        dispatch('addNowTask', {
          contrast: task.contrast,
          content: task.content,
          type: task.type
        })
        dispatch('startNowTask')
      })

      state.timedTaskList.push(task)
    },
    cancelTimedTask({ state, commit }, action) {
      const { task } = action
      cancelJob(task.id)
      commit('removeTimedTask', task)
    },
  },
}